home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / gsview10.zip / clip.c next >
C/C++ Source or Header  |  1993-08-05  |  38KB  |  1,425 lines

  1. /*
  2.  * clip.c --    Clipboard and EPS operations for GSVIEW.EXE, 
  3.  *              a graphical interface for MS-Windows Ghostscript
  4.  * Copyright (C) 1993  Russell Lang
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *   Author: Russell Lang
  21.  * Internet: rjl@monu1.cc.monash.edu.au
  22.  */
  23.  
  24. #define STRICT
  25. #include <windows.h>
  26. #include <windowsx.h>
  27. #include <commdlg.h>
  28. #include <shellapi.h>
  29. #include <mmsystem.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <ctype.h>
  34. #include <dir.h>
  35. #include <io.h>
  36. #define NeedFunctionPrototypes 1
  37. #include "ps.h"
  38. #include "gsview.h"
  39.  
  40. #include <time.h>
  41.  
  42. #define COPY_BUF_SIZE 16384u
  43.  
  44. /* Write data to file - blocks > 64k permitted */
  45. long
  46. hwrite(HFILE hf, const void _huge *hpvBuffer, long cbBuffer)
  47. {
  48. DWORD count;
  49. long written, done;
  50. char _huge *hp;
  51.     if (is_win31)
  52.         return _hwrite(hf, hpvBuffer, cbBuffer);
  53.     done = 0;
  54.     hp = (char _huge *)hpvBuffer;
  55.     while (cbBuffer > 0) {
  56.         count = min( min(32768UL, cbBuffer), (DWORD)(65536UL-OFFSETOF(hp)) );
  57.         written = _lwrite(hf, hp, (UINT)count);
  58.         if (written == (long)HFILE_ERROR)
  59.         return (long)HFILE_ERROR;
  60.         done += written;
  61.         cbBuffer -= written;
  62.         hp += written;
  63.     }
  64.     return done;
  65. }
  66.  
  67. /* return number of bytes per line, rounded up to multiple of 4 bytes */
  68. LONG
  69. dib_bytewidth(LPBITMAPINFOHEADER pbmih)
  70. {
  71.  return (((pbmih->biWidth * pbmih->biBitCount + 31) & ~31) >> 3);
  72. }
  73.  
  74. /* return number of colors in color table */
  75. UINT
  76. dib_pal_colors(LPBITMAPINFOHEADER pbmih)
  77. {
  78. int bits_per_pixel = pbmih->biPlanes * pbmih->biBitCount;
  79.     if (bits_per_pixel != 24) {
  80.         if (pbmih->biSize == sizeof(BITMAPCOREHEADER)) {
  81.         return 1<<bits_per_pixel;
  82.         }
  83.         else {
  84.         return (pbmih->biClrUsed) ? (UINT)(pbmih->biClrUsed) : 1<<bits_per_pixel;
  85.         }
  86.     }
  87.     return 0;
  88. }
  89.  
  90. /* copy a DIB from the clipboard to a file */
  91. void
  92. clip_to_file(void)
  93. {
  94. HGLOBAL hglobal;
  95. LPBITMAPINFOHEADER pbmih;
  96. BITMAPFILEHEADER bmfh;
  97. UINT palcolors;
  98. UINT palsize;
  99. DWORD bitmap_size;
  100. BYTE _huge *lpBits;
  101. static char output[MAXSTR];
  102. HFILE hfile;
  103.     if (!OpenClipboard(hwndimg)) {
  104.         play_sound(SOUND_ERROR);
  105.         return;
  106.     }
  107.     if (!IsClipboardFormatAvailable(CF_DIB)) {
  108.         CloseClipboard();
  109.         play_sound(SOUND_ERROR);
  110.         return;
  111.     }
  112.     hglobal = (HGLOBAL)GetClipboardData(CF_DIB);
  113.     pbmih = (LPBITMAPINFOHEADER)GlobalLock(hglobal);
  114.     palcolors = dib_pal_colors(pbmih);
  115.     if (pbmih->biSize == sizeof(BITMAPCOREHEADER))
  116.         palsize = palcolors * sizeof(RGBTRIPLE); 
  117.     else
  118.         palsize = palcolors * sizeof(RGBQUAD);
  119.     bitmap_size = (DWORD)pbmih->biHeight *  dib_bytewidth(pbmih);
  120.  
  121.     bmfh.bfType = ('M'<<8) | 'B';
  122.     bmfh.bfReserved1 = 0;
  123.     bmfh.bfReserved2 = 0;
  124.     bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + pbmih->biSize + palsize;
  125.     bmfh.bfSize = bmfh.bfOffBits + bitmap_size;
  126.  
  127.     if ( getfilename(output, SAVE, FILTER_BMP, NULL, IDS_TOPICEDIT)
  128.         && ((hfile = _lcreat(output, 0)) != HFILE_ERROR) ) {
  129.         hwrite(hfile, &bmfh, sizeof(BITMAPFILEHEADER));
  130.         hwrite(hfile, pbmih, pbmih->biSize + palsize);
  131.         lpBits =  ((BYTE _huge *)pbmih) + pbmih->biSize + palsize;
  132.         hwrite(hfile, lpBits, bitmap_size);
  133.         _lclose(hfile);
  134.     }
  135.     GlobalUnlock(hglobal);
  136.     CloseClipboard();
  137. }
  138.  
  139. /* convert bitmap (DIB or DDB) in clipboard to */
  140. /* CF_DIB, CF_BITMAP and CF_PALETTE */
  141. void
  142. clip_convert(void)
  143. {
  144.     if (!OpenClipboard(hwndimg)) {
  145.         play_sound(SOUND_ERROR);
  146.         return;
  147.     }
  148.     if (IsClipboardFormatAvailable(CF_DIB)) {
  149.         if (!IsClipboardFormatAvailable(CF_PALETTE))
  150.         clip_add_palette();
  151.         if (!IsClipboardFormatAvailable(CF_BITMAP))
  152.             clip_add_ddb();
  153.     }
  154.     else {
  155.         if (IsClipboardFormatAvailable(CF_BITMAP)) {
  156.         clip_add_dib();
  157.             if (!IsClipboardFormatAvailable(CF_PALETTE))
  158.             clip_add_palette();
  159.         }
  160.         else 
  161.         play_sound(SOUND_ERROR);
  162.     }
  163.     CloseClipboard();
  164. }
  165.  
  166. /* Read DIB from the clipboard, create PALETTE and add to clipboard */
  167. void
  168. clip_add_palette(void)
  169. {
  170. HGLOBAL hglobal;
  171. LPBITMAPINFOHEADER pbmih;
  172. UINT palcolors;
  173. UINT palsize;
  174. int i;
  175. LPLOGPALETTE logpalette;
  176. HPALETTE hpalette;
  177. RGBQUAD FAR *prgbquad;
  178. RGBTRIPLE FAR *prgbtriple;
  179.  
  180.     if (!IsClipboardFormatAvailable(CF_DIB)) {
  181.         play_sound(SOUND_ERROR);
  182.         return;
  183.     }
  184.     hglobal = (HGLOBAL)GetClipboardData(CF_DIB);
  185.     pbmih = (LPBITMAPINFOHEADER)GlobalLock(hglobal);
  186.     palcolors = dib_pal_colors(pbmih);
  187.     if (pbmih->biSize == sizeof(BITMAPCOREHEADER))
  188.         palsize = palcolors * sizeof(RGBTRIPLE); 
  189.     else
  190.         palsize = palcolors * sizeof(RGBQUAD);
  191.     hpalette = (HPALETTE)NULL;
  192.     if (palsize) {
  193.         /* create palette to match DIB */
  194.         logpalette = (LPLOGPALETTE) malloc( sizeof(LOGPALETTE) + 
  195.         palcolors * sizeof(PALETTEENTRY) );
  196.         if (logpalette == (LPLOGPALETTE)NULL) {
  197.         GlobalUnlock(hglobal);
  198.         play_sound(SOUND_ERROR);
  199.         return;
  200.         }
  201.         logpalette->palVersion = 0x300;
  202.         logpalette->palNumEntries = palcolors;
  203.         prgbquad = (RGBQUAD FAR *)(((BYTE _huge *)pbmih) + pbmih->biSize);
  204.         if (pbmih->biSize == sizeof(BITMAPCOREHEADER)) {
  205.         /* OS2 format */
  206.             prgbtriple = (RGBTRIPLE FAR *)prgbquad;
  207.             for (i=0; i<palcolors; i++) {
  208.                 logpalette->palPalEntry[i].peFlags = 0;
  209.             logpalette->palPalEntry[i].peRed   = prgbtriple[i].rgbtRed;
  210.             logpalette->palPalEntry[i].peGreen = prgbtriple[i].rgbtGreen;
  211.             logpalette->palPalEntry[i].peBlue  = prgbtriple[i].rgbtBlue;
  212.             }
  213.         }
  214.         else {
  215.         /* Windows Format */
  216.             for (i=0; i<palcolors; i++) {
  217.                 logpalette->palPalEntry[i].peFlags = 0;
  218.             logpalette->palPalEntry[i].peRed   = prgbquad[i].rgbRed;
  219.             logpalette->palPalEntry[i].peGreen = prgbquad[i].rgbGreen;
  220.             logpalette->palPalEntry[i].peBlue  = prgbquad[i].rgbBlue;
  221.             }
  222.         }
  223.         hpalette = CreatePalette(logpalette);
  224.         free((void *)logpalette);
  225.         SetClipboardData(CF_PALETTE, hpalette);
  226.     }
  227.     GlobalUnlock(hglobal);
  228. }
  229.  
  230.  
  231. /* Read DIB from the clipboard, convert to DDB and add to clipboard */
  232. void
  233. clip_add_ddb(void)
  234. {
  235. HGLOBAL hglobal;
  236. LPBITMAPINFOHEADER pbmih;
  237. UINT palcolors;
  238. UINT palsize;
  239. HPALETTE hpalette;
  240. HDC hdc;
  241. HBITMAP hbitmap;
  242.  
  243.     hglobal = (HGLOBAL)GetClipboardData(CF_DIB);
  244.     pbmih = (LPBITMAPINFOHEADER)GlobalLock(hglobal);
  245.     palcolors = dib_pal_colors(pbmih);
  246.     if (pbmih->biSize == sizeof(BITMAPCOREHEADER))
  247.         palsize = palcolors * sizeof(RGBTRIPLE); 
  248.     else
  249.         palsize = palcolors * sizeof(RGBQUAD);
  250.  
  251.     hdc = GetDC(hwndimg);
  252.     hpalette = GetClipboardData(CF_PALETTE);
  253.     if (hpalette) {
  254.         SelectPalette(hdc,hpalette,NULL);
  255.         RealizePalette(hdc);
  256.     }
  257.     hbitmap = CreateDIBitmap(hdc, pbmih, CBM_INIT,
  258.         ((BYTE _huge *)pbmih) + pbmih->biSize + palsize,
  259.         (LPBITMAPINFO)pbmih, DIB_RGB_COLORS);
  260.     ReleaseDC(hwndimg, hdc);
  261.     GlobalUnlock(hglobal);
  262.     SetClipboardData(CF_BITMAP, hbitmap);
  263. }
  264.  
  265. /* make a DIB from a BITMAP in the clipboard */
  266. /* GetDIBits won't work for 4 plane or 4 bit/pixel bitmaps */
  267. /* clipboard must be open */
  268. HGLOBAL 
  269. make_dib(void)
  270. {
  271. LPBITMAPINFOHEADER pbmih;
  272. LPBITMAPINFO pbmi;
  273. BYTE FAR *lpBits;
  274. HBITMAP hbitmap;
  275. UINT palcolors;
  276. UINT palsize;
  277. UINT byte_width;
  278. DWORD bitmap_size;
  279. HGLOBAL hglobal;
  280. HDC hdc;
  281. HDC hdc_bit;
  282. BITMAP bm;
  283. PALETTEENTRY *pe;
  284. int i;
  285.     hbitmap = GetClipboardData(CF_BITMAP);
  286.     hdc = GetDC((HWND)NULL);
  287.     hdc_bit = CreateCompatibleDC(hdc);
  288.     ReleaseDC((HWND)NULL,hdc);
  289.     GetObject(hbitmap, sizeof(BITMAP), &bm);
  290.     if (bm.bmPlanes == 4) {
  291.         HBITMAP hbitmap_new, hbitmap_old;
  292.         HDC hdc_new;
  293.         /